const { dialog, net, shell, BrowserWindow, app } = require("electron");
const fs = require("fs");
const path = require("path");

const activeDownloads = new Map();

/**
 * 设置日志文件输出
 * @param {string} appName - 应用名称，用于日志文件名
 * @returns {string} 日志文件路径
 */
function setupLogging(appName = 'app') {
  const logDir = path.join(app.getPath('userData'), 'logs');
  if (!fs.existsSync(logDir)) {
    fs.mkdirSync(logDir, { recursive: true });
  }

  const logFile = path.join(logDir, `${appName}-${new Date().toISOString().split('T')[0]}.log`);

  // 保存原始的console方法
  const originalLog = console.log;
  const originalError = console.error;
  const originalWarn = console.warn;

  function writeToLog(level, ...args) {
    const timestamp = new Date().toISOString();
    const message = args.map(arg => 
      typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
    ).join(' ');
    const logEntry = `[${timestamp}] [${level}] ${message}\n`;
    
    try {
      fs.appendFileSync(logFile, logEntry, 'utf8');
    } catch (error) {
      // 如果写入日志文件失败，至少保持控制台输出
      originalError('Failed to write to log file:', error.message);
    }
  }

  // 重写console方法
  console.log = (...args) => {
    originalLog(...args);
    writeToLog('INFO', ...args);
  };

  console.error = (...args) => {
    originalError(...args);
    writeToLog('ERROR', ...args);
  };

  console.warn = (...args) => {
    originalWarn(...args);
    writeToLog('WARN', ...args);
  };

  console.log('日志系统初始化完成，日志文件路径:', logFile);
  return logFile;
}

const logsDir = (() => {
  // 尝试使用应用安装目录
  const exeDir = app.getPath('exe');
  const baseDir = process.env.NODE_ENV === 'development'
    ? path.resolve(__dirname, '..')
    : path.dirname(exeDir);
  const logs = path.join(baseDir, 'logs');
  
  try {
    if (!fs.existsSync(logs)) {
      fs.mkdirSync(logs, { recursive: true });
    }
    return logs;
  } catch (error) {
    console.warn('无法在安装目录创建logs文件夹，使用用户数据目录:', error.message);
    // 备用方案：使用用户数据目录
    const userDataPath = app.getPath('userData');
    const fallbackLogs = path.join(userDataPath, 'logs');
    if (!fs.existsSync(fallbackLogs)) {
      fs.mkdirSync(fallbackLogs, { recursive: true });
    }
    return fallbackLogs;
  }
})();

function getDefaultDownloadDir() {
  // 尝试使用应用安装目录
  const exeDir = app.getPath('exe');
  const baseDir = process.env.NODE_ENV === 'development'
    ? path.resolve(__dirname, '..')
    : path.dirname(exeDir);
  const downloadsDir = path.join(baseDir, 'downloads');
  
  try {
    if (!fs.existsSync(downloadsDir)) {
      fs.mkdirSync(downloadsDir, { recursive: true });
    }
    return downloadsDir;
  } catch (error) {
    console.warn('无法在安装目录创建downloads文件夹，使用用户数据目录:', error.message);
    // 备用方案：使用用户数据目录
    const userDataPath = app.getPath('userData');
    const fallbackDownloads = path.join(userDataPath, 'downloads');
    if (!fs.existsSync(fallbackDownloads)) {
      fs.mkdirSync(fallbackDownloads, { recursive: true });
    }
    return fallbackDownloads;
  }
}

/**
 * 检查文件是否存在
 * @param {string} filePath - 文件路径
 * @returns {boolean} 文件是否存在
 */
function checkFileExists(filePath) {
  try {
    return fs.existsSync(filePath);
  } catch (error) {
    console.error("检查文件存在失败:", error);
    return false;
  }
}

/**
 * 打开文件所在位置
 * @param {string} filePath - 文件路径
 */
function openFileLocation(filePath) {
  try {
    shell.showItemInFolder(filePath);
  } catch (error) {
    console.error("打开文件位置失败:", error);
    // 备用方案：打开文件所在目录
    shell.openPath(path.dirname(filePath));
  }
}

/**
 * 发送下载完成通知
 * @param {string} filePath - 文件保存路径
 * @param {Function} getStaticPath - 获取静态路径的函数
 * @param {boolean} isDevelopment - 是否为开发环境
 */
function sendDownloadCompleteNotification(filePath, getStaticPath, isDevelopment) {
  const { Notification } = require("electron");
  
  const notification = new Notification({
    title: "下载完成",
    body: `文件已保存到: ${path.basename(filePath)}`,
    subtitle: path.dirname(filePath),
    icon: getStaticPath(isDevelopment, "image/favicon.ico"),
    silent: false,
  });
  
  notification.show();
  
  // 点击通知时打开文件所在位置
  notification.on("click", () => {
    try {
      // 在文件管理器中显示文件
      shell.showItemInFolder(filePath);
    } catch (error) {
      console.error("Failed to open file location:", error);
      // 备用方案：打开文件所在目录
      shell.openPath(path.dirname(filePath));
    }
  });
}

/**
 * 截断过长的链接，显示开头和结尾
 * @param {string} url - 要截断的URL
 * @param {number} maxLength - 最大长度，默认80
 * @returns {string} 截断后的URL
 */
function truncateUrl(url, maxLength = 80) {
  if (url.length <= maxLength) {
    return url;
  }
  
  const startLength = Math.floor(maxLength * 0.4); // 开头占40%
  const endLength = Math.floor(maxLength * 0.4);   // 结尾占40%
  
  const start = url.substring(0, startLength);
  const end = url.substring(url.length - endLength);
  
  return `${start}...${end}`;
}

/**
 * 打开外部链接
 * @param {BrowserWindow} mainWindow - 主窗口
 * @param {string} url - 要打开的URL
 * @param {boolean} showDialog - 是否显示确认对话框
 */
async function openExternalLink(mainWindow, url, showDialog = false) {
  try {
    if (showDialog) {
      const truncatedUrl = truncateUrl(url);
      const result = await dialog.showMessageBox(mainWindow, {
        type: "question",
        title: "打开外部链接",
        message: "是否要在系统默认浏览器中打开以下链接？",
        detail: truncatedUrl,
        buttons: ["打开", "取消"],
        defaultId: 0,
        cancelId: 1,
      });

      if (result.response === 0) {
        await shell.openExternal(url);
      }
    } else {
      await shell.openExternal(url);
    }
  } catch (error) {
    console.error("Failed to open external link:", error);
  }
}

/**
 * 下载外部文件
 * @param {BrowserWindow} mainWindow - 主窗口
 * @param {string} url - 文件URL
 * @param {string} filename - 文件名
 * @param {Function} getStaticPath - 获取静态路径的函数
 * @param {boolean} isDevelopment - 是否为开发环境
 * @param {Function} onProgress - 进度回调函数
 */
async function downloadExternalFile(mainWindow, url, filename, getStaticPath, isDevelopment, onProgress) {
  try {
    // 获取默认下载目录
    const downloadsDir = getDefaultDownloadDir();
    const defaultPath = path.join(downloadsDir, filename);
    // 显示保存对话框
    const result = await dialog.showSaveDialog(mainWindow, {
      title: "保存文件",
      defaultPath,
      filters: [
        { name: "所有文件", extensions: ["*"] }
      ]
    });
    
    if (!result.canceled && result.filePath) {
      // 生成字符串类型的下载ID
      const downloadId = Date.now().toString() + Math.random().toString(36).slice(2);
      // 通知渲染进程添加下载任务
      if (onProgress) {
        onProgress('add', downloadId, { downloadId, filename, filePath: result.filePath });
      }
      // 使用net模块下载文件
      const request = net.request(url);
      const writeStream = fs.createWriteStream(result.filePath);
      // 保存到Map，便于取消
      activeDownloads.set(downloadId, { request, writeStream, filePath: result.filePath });
      let downloadedBytes = 0;
      let totalBytes = 0;
      let startTime = Date.now();
      request.on('response', (response) => {
        totalBytes = parseInt(response.headers['content-length'] || '0');
        response.on('data', (chunk) => {
          downloadedBytes += chunk.length;
          writeStream.write(chunk);
          let progress = 0;
          if (totalBytes > 0) {
            progress = Math.round((downloadedBytes / totalBytes) * 100);
          }
          const elapsed = (Date.now() - startTime) / 1000;
          const speed = elapsed > 0 ? `${(downloadedBytes / 1024 / elapsed).toFixed(1)} KB/s` : '0 KB/s';
          if (onProgress && totalBytes > 0) {
            onProgress('progress', downloadId, { progress, speed });
          }
        });
        response.on('end', () => {
          writeStream.end();
          if (onProgress) {
            onProgress('progress', downloadId, { progress: 100, speed: '0 KB/s' });
            onProgress('complete', downloadId, { filePath: result.filePath });
          }
          sendDownloadCompleteNotification(result.filePath, getStaticPath, isDevelopment);
          activeDownloads.delete(downloadId);
        });
      });
      request.on('error', (error) => {
        console.error('Download error:', error);
        writeStream.end();
        fs.unlink(result.filePath, () => {});
        if (onProgress) {
          onProgress('error', downloadId, { error: error.message });
        }
        dialog.showErrorBox("下载失败", `文件下载失败：${error.message}\n请检查网络连接或重试。`);
        activeDownloads.delete(downloadId);
      });
      request.end();
    }
  } catch (error) {
    console.error("Failed to download file:", error);
    dialog.showErrorBox("下载失败", `文件下载失败：${error.message}\n请检查网络连接或重试。`);
  }
}

/**
 * 下载blob数据
 * @param {BrowserWindow} mainWindow - 主窗口
 * @param {Buffer} data - 文件数据
 * @param {string} filename - 文件名
 * @param {string} mimeType - MIME类型
 * @param {Function} getStaticPath - 获取静态路径的函数
 * @param {boolean} isDevelopment - 是否为开发环境
 * @param {Function} onProgress - 进度回调函数
 */
async function downloadBlobData(mainWindow, data, filename, mimeType, getStaticPath, isDevelopment, onProgress) {
  try {
    // 获取默认下载目录
    const downloadsDir = getDefaultDownloadDir();
    const defaultPath = path.join(downloadsDir, filename);
    // 显示保存对话框
    const result = await dialog.showSaveDialog(mainWindow, {
      title: "保存文件",
      defaultPath,
      filters: [
        { name: "所有文件", extensions: ["*"] }
      ]
    });
    if (!result.canceled && result.filePath) {
      // 生成字符串类型的下载ID
      const downloadId = Date.now().toString() + Math.random().toString(36).slice(2);
      // 通知渲染进程添加下载任务
      if (onProgress) {
        onProgress('add', downloadId, { downloadId, filename, filePath: result.filePath });
      }
      // 模拟进度更新
      if (onProgress) {
        onProgress('progress', downloadId, { progress: 50, speed: '0 KB/s' });
      }
      fs.writeFileSync(result.filePath, data);
      // 通知渲染进程下载完成
      if (onProgress) {
        onProgress('progress', downloadId, { progress: 100, speed: '0 KB/s' });
        onProgress('complete', downloadId, { filePath: result.filePath });
      }
      // 发送下载完成通知
      sendDownloadCompleteNotification(result.filePath, getStaticPath, isDevelopment);
    }
  } catch (error) {
    console.error("Failed to save file:", error);
    
    // 通知渲染进程下载失败
    if (onProgress) {
      const downloadId = Date.now().toString() + Math.random().toString(36).slice(2);
      onProgress('error', downloadId, { error: error.message });
    }
    
    // 使用dialog提示保存失败
    dialog.showErrorBox("保存失败", `文件保存失败：${error.message}\n请检查文件路径或权限。`);
  }
}

/**
 * 创建打印窗口
 * @param {string} fileUrl - 文件URL
 * @returns {BrowserWindow} 打印窗口实例
 */
function createPrintWindow(fileUrl) {  
  let printWin = new BrowserWindow({
    show: true,
    width: 800,
    height: 600,
    webPreferences: {
      sandbox: true,
    },
  });
  printWin.setMenu(null);
  
  // 判断文件类型
  if (fileUrl.endsWith(".pdf")) {
    printWin.loadURL(fileUrl);
  } else if (/\.(png|jpg|jpeg|gif)$/i.test(fileUrl)) {
    // 用HTML包裹图片，保证图片自适应窗口
    const html = `<body style="margin:0;display:flex;align-items:center;justify-content:center;background:#fff;">
      <img src="${fileUrl}" style="max-width:100vw;max-height:100vh;"/>
    </body>`;
    printWin.loadURL(
      "data:text/html;charset=utf-8," + encodeURIComponent(html)
    );
  } else {
    // 其他类型可扩展
    printWin.close();
    return null;
  }
  
  return printWin;
}

/**
 * 设置打印窗口事件监听
 * @param {BrowserWindow} printWin - 打印窗口
 */
function setupPrintWindowEvents(printWin) {
  printWin.webContents.once("did-stop-loading", () => {
    setTimeout(() => {
      if (printWin && !printWin.isDestroyed()) {
        printWin.show();
        printWin.focus();
        printWin.webContents.print(
          { silent: false },
          (success, errorType) => {
            if (!success) {
              console.error("打印失败:", errorType);
            }
            if (printWin && !printWin.isDestroyed()) {
              printWin.close();
            }
          }
        );
      }
    }, 400);
  });

  printWin.on("closed", () => {
    printWin = null;
  });
}

/**
 * 打印文件
 * @param {string} fileUrl - 文件URL
 */
async function printFile(fileUrl) {
  const printWin = createPrintWindow(fileUrl);
  if (printWin) {
    setupPrintWindowEvents(printWin);
  }
}

function getDownloadHistoryPath() {
  const filePath = path.join(logsDir, 'download-history.log');
  if (!fs.existsSync(filePath)) {
    fs.writeFileSync(filePath, '[]', 'utf-8');
  }
  return filePath;
}

function readDownloadHistory() {
  const filePath = getDownloadHistoryPath();
  try {
    const content = fs.readFileSync(filePath, 'utf-8');
    return JSON.parse(content || '[]');
  } catch (e) {
    return [];
  }
}

function writeDownloadHistory(history) {
  const filePath = getDownloadHistoryPath();
  fs.writeFileSync(filePath, JSON.stringify(history, null, 2), 'utf-8');
}

module.exports = {
  setupLogging,
  truncateUrl,
  openExternalLink,
  downloadExternalFile,
  downloadBlobData,
  createPrintWindow,
  setupPrintWindowEvents,
  printFile,
  sendDownloadCompleteNotification,
  checkFileExists,
  openFileLocation,
  activeDownloads,
  readDownloadHistory,
  writeDownloadHistory
};
